﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Collections;
using System.Windows.Data;
using System.Diagnostics;

namespace SwiftMVVM.Behaviors
{
    /// <summary>
    /// TextBoxBehavior defines a set of reusable behaviors normally coded against a listbox.
    /// Such as AutoSelection on mouse hover.
    /// </summary>
    public sealed class ListBoxBehavior
    {
      

        /// <summary>
        /// AutoSelectOnMouseHover dependency property getter
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public static bool GetAutoSelectOnMouseHover(DependencyObject d)
        {
            return (bool)d.GetValue(AutoSelectOnMouseHoverProperty);
        }

        /// <summary>
        /// AutoSelectOnMouseHover dependency property setter
        /// </summary>
        /// <param name="d"></param>
        /// <param name="value"></param>
        public static void SetAutoSelectOnMouseHover(DependencyObject d, bool value)
        {
            d.SetValue(AutoSelectOnMouseHoverProperty, value);
        }

        /// <summary>
        /// This behavior simulates the auto selection of the standard undo buttons
        /// in various editor programs by selecting the rows in the listbox on mouse hover
        /// </summary>
        public static readonly DependencyProperty AutoSelectOnMouseHoverProperty =
           DependencyProperty.RegisterAttached(
           "AutoSelectOnMouseHover",
           typeof(bool),
           typeof(ListBoxBehavior),
           new FrameworkPropertyMetadata(false, (d, e) =>
           {
               var listBox = d as ListBox;
               if (listBox != null)
               {
                   //Hook the loaded event of the listbox so we can be sure to auto select the first item
                   listBox.Loaded += new RoutedEventHandler(listBox_Loaded);

                  
                   listBox.SelectionMode = SelectionMode.Multiple;
                   var itemStyle = new Style(typeof(ListBoxItem));
                   itemStyle.Setters.Add(new EventSetter(ListBoxItem.MouseEnterEvent,
                       new MouseEventHandler((sender, args) =>
                       {
                           var listBoxItem = (ListBoxItem)sender;
                           int currentIndex = listBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
                           for (int i = 0; i < listBox.Items.Count; i++)
                           {
                               var item = listBox.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
                               if (item != null)
                               {
                                   item.IsSelected = i <= currentIndex;
                               }
                           }
                       })));

                   listBox.Resources.Add(typeof(ListBoxItem), itemStyle);
               }
           })
           );

        static void listBox_Loaded(object sender, RoutedEventArgs e)
        {
            var listBox = sender as ListBox;
            listBox.Loaded -= new RoutedEventHandler(listBox_Loaded);
            if (listBox.Items.Count > 0)
            {
                var item = listBox.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem;
                if (item != null)
                {
                    item.IsSelected = true;
                }
            }
        }
    }
}
